package com.ruoyi.oauth.utils;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.oauth.sso.vo.OAuthCode;
import com.ruoyi.oauth.sso.vo.OAuthRequest;

import javax.servlet.http.HttpServletRequest;

/**
 * 单点登录解析工具类
 */
public class OAuthUtil {
    public final static String OAUTH_CLIENT_ID = "client_id";
    public final static String OAUTH_CLIENT_SECRET = "client_secret";
    public final static String OAUTH_CODE = "code";
    public final static String OAUTH_SCOPE = "scope";
    public final static String OAUTH_RESPONSE_TYPE = "response_type";
    public final static String OAUTH_REFRESH_TOKEN = "refresh_token";
    public final static String OAUTH_ACCESS_TOKEN = "access_token";
    public final static String OAUTH_GRANT_TYPE = "grant_type";
    public final static String OAUTH_REDIRECT_URI = "redirect_uri";
    public final static String OAUTH_STATE = "state";
    public final static String OAUTH_HEADER_AUTHORIZATION = "Authorization";
    public final static String OAUTH_HEADER_NAME = "Bearer";
    public final static String OAUTH_USERNAME = "username";
    public final static String OAUTH_PASSWORD = "password";



    /**
     * 从请求中获取code值
     * code通过code=****直接赋值
     *
     * @param request
     * @return
     */
    public static String getCode(HttpServletRequest request) {
        return request.getParameter(OAUTH_CODE);
    }

    /**
     * 从请求中获取client_secret值
     * client_secret通过client_secret=****直接赋值
     *
     * @param request
     * @return
     */
    public static String getClientSecret(HttpServletRequest request) {
        return request.getParameter(OAUTH_CLIENT_SECRET);
    }

    /**
     * 从请求中获取client_id值
     * client_id通过client_id=****直接赋值
     *
     * @param request
     * @return
     */
    public static String getClientId(HttpServletRequest request) {
        return request.getParameter(OAUTH_CLIENT_ID);
    }

    /**
     * 从请求中获取scope值
     * scope通过scope=****直接赋值
     *
     * @param request
     * @return
     */
    public static String getScope(HttpServletRequest request) {
        return request.getParameter(OAUTH_SCOPE);
    }

    /**
     * 从请求中获取 state 值
     * state 通过 state = ****直接赋值
     *
     * @param request
     * @return
     */
    public static String getState(HttpServletRequest request) {
        return request.getParameter(OAUTH_STATE);
    }

    /**
     * 从请求中获取 redirect_uri 值
     * redirect_uri 通过 redirect_uri = ****直接赋值
     *
     * @param request
     * @return
     */
    public static String getRedirectUri(HttpServletRequest request) {
        return request.getParameter(OAUTH_REDIRECT_URI);
    }

    /**
     * 从请求中获取 response_type 值
     * response_type 通过 response_type = ****直接赋值
     *
     * @param request
     * @return
     */
    public static String getResponseType(HttpServletRequest request) {
        return request.getParameter(OAUTH_RESPONSE_TYPE);
    }

    /**
     * 从请求中获取refresh_token值
     * refresh_token通过refresh_token=****直接赋值
     *
     * @param request
     * @return
     */
    public static String getRefreshToken(HttpServletRequest request) {
        return request.getParameter(OAUTH_REFRESH_TOKEN);
    }

    /**
     * 从请求中获取token值
     * token通过access_token=****直接赋值
     * 或者token放到head中 以Authorization=Bearer******方式传入
     *
     * @param request
     * @return
     */
    public static String getAccessToken(HttpServletRequest request) {
        String accessToken = request.getParameter(OAUTH_ACCESS_TOKEN);
        // 请求参数中包含access_token参数
        if (StringUtils.isEmpty(accessToken)) {
            // 头部的Authorization值以Bearer开头
            String auth = request.getHeader(OAUTH_HEADER_AUTHORIZATION);
            if (auth != null && auth.startsWith(OAUTH_HEADER_NAME)) {
                accessToken = auth.replace(OAUTH_HEADER_NAME, "").trim();
            }
        }
        return accessToken;
    }

    /**
     * 获取请求用户IP
     *
     * @param request
     * @return
     */
    public static String getRemoteIP(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ip != null && ip.length() > 15) {
            if (ip.indexOf(',') > 0) {
                ip = ip.substring(0, ip.indexOf(','));
            }
        }
        return ip;
    }

    /**
     * 构建code响应URI
     * @param request
     * @param code
     * @return
     */
    public static String buildCodeResponse(OAuthRequest request, OAuthCode code){
        String uri = request.getRedirectUri();
        if(request.getRedirectUri().indexOf("?") > 0){
            uri += "&code="+code.getCode();
        }else{
            uri += "?code="+code.getCode();
        }
        return uri+ "&state="+request.getState();
    }

    /**
     * 生成验证码
     *
     * @return
     */
    public static String buildCode(){
        return UUID.fastUUID().toString(true);
    }

    /**
     * 生成令牌
     *
     * @return
     */
    public static String buildToken(){
        return UUID.fastUUID().toString(true);
    }
}
